package com.woniu.cms.auth.core.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.woniu.cms.auth.core.entity.RbacUser;
import com.woniu.cms.auth.core.service.IRbacUserService;
import com.woniu.cms.auth.core.vo.*;
import com.woniu.common.api.Result;
import com.woniu.common.api.constant.RedisTokenConstant;
import com.woniu.common.api.status.IStatusCode;
import com.woniu.common.api.status.Impl.BusinessCode;
import com.woniu.common.api.util.JWTUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.lang.Nullable;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author lilili
 * @since 2022-09-16
 */
@RestController
@RequestMapping("/rbac-user")
@Api(tags="用户控制器")
public class RbacUserController {
    @Resource
    private IRbacUserService userService;
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 登录
     *
     * @param user     用户
     * @param response 响应
     * @return {@link Result}<{@link UserVo}>
     */
    @ApiOperation("用户登录")
    @GetMapping("/login")
    public Result<UserVo> login(LoginVo user, HttpServletResponse response){
        RbacUser one = userService.getOne(new LambdaQueryWrapper<RbacUser>().eq(RbacUser::getUserName, user.getUserName()));
        if(one == null){
            return Result.error(BusinessCode.LOGIN_FAIL);
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if(!encoder.matches(user.getPassword(), one.getPassword())){
            return Result.error(BusinessCode.LOGIN_FAIL);
        }

        //用户名和密码均正确
        UserVo userVo = userService.getUserVo(one.getId());
        Result<UserVo> result = Result.common(userVo);

        String jwt = RedisTokenConstant.TOKEN_PRE.getStatus()+ JWTUtil.generateToken(user.getUserName());

        //生成refreshToken
        String refreshToken =  UUID.randomUUID().toString().replace("-", "");

        //放到redis中,并设置refreshToken过期时间，用户如果在时间内没有任何一次操作，之后便需要重新登录
        redisTemplate.opsForValue().set(RedisTokenConstant.REFRESH_TOKEN_PRE.getStatus() + refreshToken, jwt, JWTUtil.REFRESH_TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);


        //生成响应头
        response.setHeader("authorization", jwt);
        response.setHeader("refreshToken", refreshToken);
        //暴露头，authorization和refreshToken
        response.setHeader("Access-Control-Expose-Headers","authorization,refreshToken");

        return result;
    }

    /**
     * 注册
     *
     * @param user 用户
     * @return {@link Result}<{@link String}>
     */
    @ApiOperation("用户注册")
    @PostMapping("/register")
    public Result<String> register(LoginVo user){
        RbacUser rbacUser = new RbacUser();
        rbacUser.setUserName(user.getUserName());
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        rbacUser.setPassword(encoder.encode(user.getPassword()));
        boolean save = userService.save(rbacUser);
        if(save){
            return Result.common("注册成功");
        }else{
            return Result.common("注册失败");
        }
    }

    @ApiOperation("获取所有用户的分页数据")
    @PostMapping("/register/{pageNo}/{pageSize}")
    public Result<PageUserVo> page(@PathVariable("pageNo") Integer pageNo, @PathVariable("pageSize") Integer pageSize){
        PageUserVo page = userService.getPageUserVo(pageNo, pageSize);
        return Result.common(page);
    }


    @ApiOperation("获取用户名模糊查询的用户的分页数据")
    @PostMapping("/register/{pageNo}/{pageSize}/{like}")
    public Result<PageUserVo> pagelike(@PathVariable("pageNo") Integer pageNo, @PathVariable("pageSize") Integer pageSize, @PathVariable("like")@Nullable String like){
        PageUserVo page = userService.getLikePageUserVo(pageNo, pageSize, like);
        return Result.common(page);
    }

    @ApiOperation("修改用户")
    @PutMapping("/update")
    public Result<Object> updateUser(@RequestBody PageUser pageUser){
        boolean update = userService.updateUser(pageUser);
        return Result.common(update);
    }

    @ApiOperation("删除用户")
    @DeleteMapping("/delete/{id}")
    public Result<Object> deleteUser(@PathVariable("id") Integer id){
        boolean delete = userService.removeById(id);
        return Result.common(delete);
    }

    @ApiOperation("查找用户所有权限")
    @GetMapping("/auth/perm")
    public Result<List<PermVo>> userPerm(HttpServletRequest request){
        String userName = request.getHeader("userName");
        RbacUser user = userService.getOne(new LambdaQueryWrapper<RbacUser>().eq(RbacUser::getUserName, userName));
        Integer userId = user.getId();
        List<PermVo> list = userService.getUserPerm(userId);
        return Result.common(list);
    }


}

